﻿using System;
using System.Collections.Generic;
using System.Linq;
using LB.Server.Common;
using LB.Server.DAL.DomainEntitites;
using User = LB.Server.DAL.DomainEntitites.User;

namespace LB.Server.DAL.EntityFramework
{
    class UserRepositoryEF : IUserRepository
    {
        private readonly RepositoryDataContext dataContext;
        private readonly ApplicationLog log = new ApplicationLog();

        public WorkingSession CreateSession(string sessionId, int userId, DateTime startTime, TimeSpan sessionDuration)
        {
            try
            {
                var ws = new WorkingSession
                             {
                                 SessionId = sessionId,
                                 UserId = userId,
                                 StartTime = startTime,
                                 SessionDuration = sessionDuration
                             };
                dataContext.WorkingSessions.Add(ws);
                dataContext.SaveChanges();
                return ws;
            }catch (Exception e)
            {
                log.WriteError("Error during session saving. {0}", e.Message);
                return null;
            }
        }

        public bool ProlongateSession(string sessionId, TimeSpan duration)
        {
            try
            {
                var session = GetworkinSessionbyId(sessionId);
                session.SessionDuration += duration;
                dataContext.SaveChanges();
                return true;
            }
            catch (Exception e)
            {
                log.WriteError("Error during session prolongation. {0}", e.Message);
                return false;
            }
        }

        public bool CloseSession(string sessionId)
        {
            try
            {
                dataContext.WorkingSessions.Remove(dataContext.WorkingSessions.Where(ws => ws.SessionId == sessionId).Single());
                dataContext.SaveChanges();
                return true;
            }
            catch (Exception e)
            {
                log.WriteError("cant close session with Id - {0},\t{1}", sessionId, e.Message);
                return false;
            }
        }

        public WorkingSession IsSessionExist(string sessionId)
        {
            return dataContext.WorkingSessions.Where(ws => ws.SessionId.Equals(sessionId)).SingleOrDefault();
        }

        public List<WorkingSession> GetWorkingSessionsByUserId(int userId)
        {
            var result = dataContext.WorkingSessions.Where(ws => ws.UserId == userId).ToList();
            return result;
        }

        public bool IsLoginExist(string userName)
        {
            return dataContext.Users.Any(u => u.Login == userName);
        }

        public bool CreateAccount(string login, string password)
        {
            try
            {
                var newUser = new User(login, password);
                dataContext.Users.Add(newUser);
                dataContext.SaveChanges();
                return true;
            }
            catch (Exception e)
            {
                log.WriteError("Can't create user - {0}. \t{1}", login, e.Message);
                return false;
            }
        }

        public User GetUserBylogin(string login)
        {
            return dataContext.Users.Single(u => u.Login == login);
        }

        public UserRepositoryEF(RepositoryDataContext dataContext)
        {
            this.dataContext = dataContext;
        }

        private WorkingSession GetworkinSessionbyId(string sessionId)
        {
            var result = dataContext.WorkingSessions.Where(ws => ws.SessionId.Equals(sessionId)).Single();
            if (result == null)
                throw new NullReferenceException(string.Format("Can't get single session with id - {0}", sessionId));
            return result;
        }
    }
}